{
  LW Prtcl -- LightWave Particles

  The particles global returns functions that allow you to create particle systems
  and to read and write particle data.
  Particles are typically used by volumetric renderers to define the extent and
  local density of a volume.
  LightWave®'s Hypervoxels, for example, uses them this way.

  Based on lwprtcl.h which is:
  Copyright 1999, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}

unit LW_Prtcl;

{$mode objfpc}{$H+}

interface

uses
  LW_Types  ,
  LW_Meshes ,
  LW_Render ,
  LW_IO     ,
  LW_Globsrv;

const
  LWPSYSFUNCS_GLOBAL = 'Particle Services' ;

  { The particle services provide some functions to create and manage particle
    data, this data is made accessible to other clients by query functions that
    lookup particle data from itemIDs. These services can be used by particle
    simulator to publish their particle information, and by particle renderers
    to access the particle informations.

    A "particle system" designates a group of particles sharing the same type
    of data.
    The data is allocated by type in buffers. For example if the particles in
    a system have the following informations: Age, Position, Color.
    The particle system will have 3 data buffers, one for each type and
    the create function will take the following flags:
    LWPSB_POS | LWPSB_AGE | LWPSB_VEL.

    Once the buffers are created and filled in, they must be attached to an item
    in the scene. This can be done with the attach\detach functions, the query
    can be done with the getPSys function.                                     }

    // Particle Types
    LWPST_PRTCL = 0 ;
    LWPST_TRAIL = 1 ;

    // Buffer Flags
    LWPSB_POS  = 1 shl 0  ;  // position (float[3])
    LWPSB_SIZ  = 1 shl 1  ;  // size (float)
    LWPSB_SCL  = 1 shl 2  ;  // scale (float[3])
    LWPSB_ROT  = 1 shl 3  ;  // rotation (float[3])
    LWPSB_VEL  = 1 shl 4  ;  // velocity (float[3])
    LWPSB_AGE  = 1 shl 5  ;  // age (float)
    LWPSB_FCE  = 1 shl 6  ;  // force (float)
    LWPSB_PRS  = 1 shl 7  ;  // pressure (float)
    LWPSB_TMP  = 1 shl 8  ;  // temperature (float)
    LWPSB_MAS  = 1 shl 9  ;  // mass (float)
    LWPSB_LNK  = 1 shl 10 ;  // link to particle (for trails) (int)
    LWPSB_ID   = 1 shl 11 ;  // particle ID, unique identifier for a particle (int)
    LWPSB_ENB  = 1 shl 12 ;  // particle state (alive/limbo/dead) (char)
    LWPSB_RGBA = 1 shl 13 ;  // particle color,alpha (for display) (char[4])
    LWPSB_CAGE = 1 shl 14 ;  // collision age: time since last collision (float)
    LWPSB_RAGE = 1 shl 15 ;  // relative age: to provide information about the life expectancy
    LWPSB_POS0 = 1 shl 16 ;  // start position (float[3])
    LWPSB_SCL0 = 1 shl 17 ;  // start scale (float[3])
    LWPSB_ROT0 = 1 shl 18 ;  // start rotation (float[3])

    { Data Types }
    LWPSBT_FLOAT = 0 ;
    LWPSBT_INT   = 1 ;
    LWPSBT_CHAR  = 2 ;

    { Particle State values }
    { "Dead": particles will simply be ignored, it is possible to create them
              however merely for convenience.
      "Alive": that is the normal state. Particles in that state will be rendered.
      "Limbo": the idea behind that state is to allow particles to subsist in
               the database for a while after they die, before being totally
               removed. When switching a particle to limbo state, the particle
               age should be reset to 0 since the age is relative to the state.
    	}
    LWPST_DEAD	 = 0 ;
    LWPST_ALIVE	 = 1 ;
    LWPST_LIMBO	 = 2 ;

type
  PPLWPSys = ^PLWPSys  ;
  PLWPSys = ^TLWPSys   ;
  TLWPSys = record end ;

  PLWPSBuf = ^TLWPSBuf  ;
  TLWPSBuf = record end ;

  PLWPSBufDesc = ^TLWPSBufDesc ;
  TLWPSBufDesc = record
    Name       : PChar   ; // const
    DataType   ,
    DataSize   : Integer ;
  end;

  PLWPSysFuncs = ^TLWPSysFuncs ;
  TLWPSysFuncs = record
    // Creates a particle system with specified type of particles
    Create      : function
                  (       Flags       ,
                          Type_       : Integer      ) : PLWPSys ;
    // Destroys a particle system
    Destroy     : function
                  (       PS          : PLWPSys      ) : Integer ;
    // Allocates all buffers with specified number of particles
    Init        : function
                  (       PS          : PLWPSys      ;
                          NP          : Integer      ) : Integer ;
    // Frees all buffers
    Cleanup     : procedure
                  (       PS          : PLWPSys      ) ;
    Load        : procedure
                  (       PS          : PLWPSys      ;
                          LState      : PLWLoadState ) ;
    Save        : procedure
                  (       PS          : PLWPSys      ;
                          SState      : PLWSaveState ) ;
    // Returns number of particles
    GetPCount   : function
                  (       PS          : PLWPSys      ) : Integer ;

    // Attaches data to an item, multiple PSys can be attached to an item and multiple items can share the same data
    Attach      : procedure
                  (       PS          : PLWPSys      ;
                          ItemID      : PLWItem      ) ;
    // Detaches data
    Detach      : procedure
                  (       PS          : PLWPSys      ;
                          ItemID      : PLWItem      ) ;
    // Returns null terminated list of PSys attached to item.
    GetPSys     : function
                  (       ItemID      : PLWItem      ) : PPLWPSys ;

    // Adds a new data buffer to the system
    AddBuf      : function
                  (       PS          : PLWPSys      ;
                          Desc        : TLWPSBufDesc ) : PLWPSBuf;
    // Gets a buffer ID, given its flag
    GetBufID    : function
                  (       PS          : PLWPSys      ;
                          BufFlag     : Integer      ) : PLWPSBuf;
    // Sets a buffer en-masse by performing a memcopy from the given pointer
    SetBufData  : procedure
                  (       BufID       : PLWPSBuf     ;
                          Data        : Pointer      ) ;
    // Gets data from a buffer
    GetBufData  : procedure
                  (        BufID      : PLWPSBuf     ;
                           Data       : Pointer      ) ;

    // Adds a particle to the system
    AddParticle : function
                  (        PS         : PLWPSys      ) : Integer ;
    // Sets a particle for the given data buffer
    SetParticle : procedure
                  (        BufID      : PLWPSBuf     ;
                           Idx        : Integer      ;
                           Data       : Pointer      ) ;
    // Gets a particle data from the given buffer
    GetParticle : procedure
                  (        BufID      : PLWPSBuf     ;
                           Idx        : Integer      ;
                           Data       : Pointer      ) ;
    // Removes a particle from the system
    RemParticle : procedure
                  (        PS         : PLWPSys      ;
                           Idx        : Integer      ) ;
  end;

implementation

end.

